vcpkg 是一個跨平台的C/C++開源庫管理器(open source package manager)。猶如pip之於python、npm之於node.js,有許多語言都有這個一個套件、庫的管理工具。我們在開發一個應用程式時,往往會需要使用到一些第三方的函式庫,你可以自行將原代碼複製到你的環境中自己編譯、工作,但要讓其正常的在你的專案中運作是不簡單的,常常做到最後,還沒實際開始編寫專案的部分就在上面花了不少時間了。開源庫管理器能極大的讓你在環境中建置、安裝第三方庫的作業量大幅減少。
首先,我們可以先找到他的Github頁面。
git clone https://github.com/microsoft/vcpkg
接著透過腳本編譯vcpkg
.\vcpkg\bootstrap-vcpkg.bat
然後我需要將vcpkg與Visual Studio集成。
.\vcpkg integrate install
你會看到如下圖,集成這個動作讓你使用Visual Studio裡面建立專案的時候,內建的MSBuild去建構專案,你可以直接inculde vcpkg所安裝的第三方套件,而編譯時也會自行進行linking的動作。而若是你使用CMake來建置你的專案時,需要加上-DCMAKE_TOOLCHAIN_FILE=
的參數才能尋找到vcpkg安裝的第三方套件的位置
然後我們能vcpkg的路徑加入環境變數就完成了。
現在假設你想要安裝第三方函式庫。你可以先在vcpkg上面搜尋,而這裡我將會用opencv來示範。
vcpkg search opencv
如上圖所示,你可以看見搜尋與opencv有相關的結果與其附加項目。那接下來我們就能用指令去安裝第三方庫。
vcpkg install opencv4:x64-windows
語法如下
vcpkg install 函式庫名稱:(作業系統,預設是x86-windows)
/* 若是你想要安裝附加項目,可以透過逗號分開,若還沒安裝核心函式庫則也要加上core */
vcpkg install 函式庫名稱[core,python,ffmpeg]:(作業系統)
接著就是等待安裝。
當你安裝完成後,他
我們可以將CMakeLists修改一下
#設定CMake最低版本
cmake_minimum_required(VERSION 3.21)
#建立項目
project(test
VERSION 0.0.0
LANGUAGES CXX
)
#設定C++標準
set(CMAKE_CXX_STANDARD 17)
#設定變數SOURCE 存放原始碼C++檔案
set(SOURCES
src/Source.cpp
)
#設定變數HEADERS 存放標頭檔
set(HEADERS
)
#尋找OpenCV REQUIRED參數代表必須找到,否則會提示錯誤
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
#設定項目中的source files
add_executable(test ${SOURCES} ${HEADERS})
#連接專案與OpenCV專案
target_link_libraries(test ${OpenCV_LIBS} )
如果我們直接跑cmake的話會發現他出現了下圖這個錯誤,找不到Opencv的位置。那我們上面有提到,如果要用CMake來建構專案卻使用vcpkg管理第三方套件的時候需要加上-DCMAKE_TOOLCHAIN_FILE=
的參數,cmake就可以找到由vcpkg所管理的套件了。
不過這裡我們也可以先看另外一種方式,我們昨天有提到Configure若是出錯,可以使用CMake-gui來更改,而在昨天安裝cmake時也一併安裝在電腦上面了,我們可以直接搜尋。
我們將Source code路徑設定為CMakeList所在的位置,而build path則是build資料夾。這時候我們會看到這個畫面。
在上面CMake Configure時會出錯是因為無法找到OpenCV這個套件,而他要我們給出含由OpenCVConfig.cmake的位置。而它的位置在哪裡呢?當我們在vcpkg install opencv結束時他有給出了兩個CMake指令。
而在上面那個OpenCV_DIR的變數值就是OpenCVConfig.cmake的所在位置,因此我們雙擊Value將值修改成 (vcpkg的位置)\vcpkg\installed\x64-windows\share\opencv4
。重新執行一次cmake指令就能成功了。
不過這方法只是暫時解決問題,當下次我們又要新增一個第三方函式庫進去時又要重新手動編輯路徑,我們可以直接指定參數讓他去尋找vcpkg管理的套件位置,而為了以後方便起見,我們將指令寫成腳本。
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=C:/(vpckg安裝的位置)/vcpkg/scripts/buildsystems/vcpkg.cmake
PAUSE
這裡有其他參數代表的意思。
那我們現在test資料夾應該會如下
test
├─ CMakeLists.txt
├─ GenerateProject.bat
└─ src
└─ Source.cpp
雙擊腳本生成解決方案後我們進去解決方案。接下來我們可以來跑一點小小的範例,這是我從github clone下來的example,一段簡單的臉部辨識範例,如果有用python寫過Opencv的人應該對此不陌生,主要內容就是load偵測臉部辨識的檔案、開啟相機、接著跑迴圈將偵測到臉部的地方渲染一個紅色方框。這裡我們將Source.cpp的內容更改成這段程式碼。
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main() {
CascadeClassifier faceDetection;
if (!faceDetection.load("../data/haarcascades/haarcascade_frontalface_default.xml")) {
cout << "XML file not loaded" << endl;
exit(0);
}
VideoCapture cap(0);
string winName = "WebCam Record";
cv::namedWindow(winName);
while (true) {
Mat img;
bool success = cap.read(img);
if (success == false) {
cout << "Video camera is disconnected" << endl;
cin.get(); //Wait for any key press
break;
}
vector<Rect> faces;
faceDetection.detectMultiScale(img, faces); //detecting faces
for (int i = 0; i < faces.size(); i++) {
Point p1(faces[i].x, faces[i].y);
Point p2((faces[i].x + faces[i].height), (faces[i].y + faces[i].width));
rectangle(img, p1, p2, Scalar(0, 0, 255), 2, 8, 0);
}
imshow("FACES", img);
if (waitKey(10) == 27) {
cout << "Esc key is pressed by user. Stoppig the video" << endl;
break;
}
}
return 0;
}
那在執行之前,我們會發現缺了一些東西。faceDetection.load()指定的XML檔案是原先被附在Opencv庫裡面Data資料夾的一個檔案,用來臉部偵測的。由於vcpkg安裝函式庫並沒有將其餘的東西一併解壓縮,因此我們可以到vcpkg的download去找出其下載的Opencv壓縮檔。
然後我們可以將data資料夾解壓縮到test資料夾。
現在的目錄應該會是這樣
test
├─ CMakeLists.txt
├─ GenerateProject.bat
├─ data
└─ src
└─ Source.cpp
接著回到解決方案中,我們就能成功的執行了。
每天就這樣不停不停地趕稿,貌似...習慣了呢
明天開始進入引擎低階系統的實作!